package android.mcsmtms.activity;

//import com.google.android.gms.maps.CameraUpdateFactory;
//import com.google.android.gms.maps.GoogleMap;
//import com.google.android.gms.maps.MapFragment;
//import com.google.android.gms.maps.model.LatLng;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.w3c.dom.Document;

import android.app.ProgressDialog;
import android.graphics.Color;
import android.mcsmtms.R;
import android.mcsmtms.constant.GlobalConstants;
import android.mcsmtms.constant.GlobalConstants.SituationTypes;
import android.mcsmtms.constant.GlobalConstants.TrafficConditionTypes;
import android.mcsmtms.domain.MobileUserReport;
import android.mcsmtms.domain.SituationReport;
import android.mcsmtms.domain.SituationSegment;
import android.mcsmtms.exception.UncaughtExceptionHandler;
import android.mcsmtms.fragment.HazardMapFragment.RenderHazardMapTask;
import android.mcsmtms.manager.GMapV2Direction;
import android.mcsmtms.rest.RestClient;
import android.mcsmtms.util.JsonHelper;
import android.mcsmtms.util.Utilities;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.InfoWindowAdapter;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.PolylineOptions;
import com.google.gson.reflect.TypeToken;

public class NotificationDetailsActivity extends FragmentActivity {
	private GoogleMap map;
	private static LatLng marikinaLatLng = new LatLng(14.650399, 121.102417);
	private SituationReport notification;
	private HashMap<String, String> markerDetailsMap = new HashMap<String, String>();
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler(this));
		
		this.requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.activity_notif_details);

		if (findViewById(R.id.container_content_fragment) != null) {

			// However, if we're being restored from a previous state,
			// then we don't need to do anything and should return or else
			// we could end up with overlapping fragments.
			if (savedInstanceState != null) {
				return;
			}
		}

		Button backBtn = (Button) findViewById(R.id.btn_back);
		backBtn.setOnClickListener(backBtnOnClickListener);
		
		FragmentManager fragmentManager = getSupportFragmentManager();
		Fragment mapFragment = fragmentManager
				.findFragmentById(R.id.map_report);
		map = ((SupportMapFragment) mapFragment).getMap();

		map.animateCamera(CameraUpdateFactory.newLatLngZoom(marikinaLatLng, 14));
		
		this.notification = (SituationReport) getIntent().getExtras().get("notification");
		
		Toast.makeText(this, "Notification Details: " + Utilities.generateSituationDetails(notification), Toast.LENGTH_LONG).show();
		//User loggedUser = Utilities.getLoggedUser(this);
		refreshNotificationMap();
	}
	
	public void refreshNotificationMap() {
		RenderSituationReport renderSituationReport = new RenderSituationReport(true, notification);
		renderSituationReport.execute();
	}
	
	public class RenderSituationReport extends AsyncTask<Void, Void, Map<String, Object>> {
		private ProgressDialog dialog;
		private boolean isRefresh = false;
		private SituationReport situationReport;
		
		public RenderSituationReport(boolean isRefreshOperation, SituationReport situationReport) {
			isRefresh = isRefreshOperation;
			this.situationReport = situationReport;
		}
		
		@SuppressWarnings("unchecked")
		@Override
		protected Map<String, Object> doInBackground(Void... params) {
			Map<String, Object> reportDetails = new HashMap<String, Object>();
			
			try {
				GMapV2Direction md = new GMapV2Direction();
				
				for(SituationSegment situationSegment : situationReport.getSituationSegmentList()) {
					LatLng fromPosition = new LatLng(situationSegment.getStartLat(), situationSegment.getStartLng());
					LatLng toPosition = new LatLng(situationSegment.getEndLat(), situationSegment.getEndLng());
					Document doc = md.getDocument(fromPosition, toPosition, GMapV2Direction.MODE_DRIVING);

					ArrayList<LatLng> directionPoint = md.getDirection(doc);
					
					int trafficColor = 0; 
					if(TrafficConditionTypes.LIGHT.getCode().equals(situationSegment.getTrafficCondition())) {
						trafficColor = Color.YELLOW;
					} else if(TrafficConditionTypes.NORMAL.getCode().equals(situationSegment.getTrafficCondition())) {
						trafficColor = Color.GREEN;
					} else if(TrafficConditionTypes.HEAVY.getCode().equals(situationSegment.getTrafficCondition())) {
						trafficColor = Color.RED;
					}
					
					PolylineOptions rectLine = new PolylineOptions().width(15).color(trafficColor);
					
					for(int i = 0 ; i < directionPoint.size() ; i++) {			
						rectLine.add(directionPoint.get(i));
					}
					
					situationSegment.setPolyLineOptions(rectLine);
				}
				
				reportDetails = new HashMap<String, Object>();
				reportDetails.put("situationReport", situationReport);
			} catch (Exception ex) {
				//Toast.makeText(getActivity(), "Error in rendering hazard hazardMap!", Toast.LENGTH_SHORT).show();
				Log.e("Hazard Map Download Error", "Error in downloading HazardMap details: " + Utilities.getErrorMessage(ex));
				return null;
			}
			
			return reportDetails;
		}
		
		@SuppressWarnings("unchecked")
		@Override
		protected void onPostExecute(Map<String, Object> reportDetails) {
			super.onPostExecute(reportDetails);
			
			if (dialog.isShowing()) {
				dialog.dismiss();
			}
			
			if(reportDetails != null) {
				try {
					map.clear();
					SituationReport reportToRender = (SituationReport) reportDetails.get("situationReport");
					if(reportToRender != null) {
						for(SituationSegment situationSegment : reportToRender.getSituationSegmentList()) {
							PolylineOptions polyLineOptions = situationSegment.getPolyLineOptions();
							//polyLineOptions.
							
							map.addPolyline(situationSegment.getPolyLineOptions());
							LatLng midPoint = new LatLng(situationSegment.getStartLat(), situationSegment.getStartLng());
							if(situationSegment.getPolyLineOptions().getPoints().size() > 0) {
								int midPointIdx = situationSegment.getPolyLineOptions().getPoints().size() / 2;
								
								midPoint = situationSegment.getPolyLineOptions().getPoints().get(midPointIdx);
							}
							
							int situationIcon = 0;
							
							if(SituationTypes.ACCIDENT.getCode().equals(situationSegment.getSituation())) {
								situationIcon = R.drawable.icon_accident;
							} else if(SituationTypes.ROAD_WORKS.getCode().equals(situationSegment.getSituation())) {
								situationIcon = R.drawable.icon_road_works;
							} else if(SituationTypes.BAD_WEATHER.getCode().equals(situationSegment.getSituation())) {
								situationIcon = R.drawable.icon_bad_weather;
							} else if(SituationTypes.BLOCKED.getCode().equals(situationSegment.getSituation())) {
								situationIcon = R.drawable.icon_road_closed;
							} else if(SituationTypes.FLOOD.getCode().equals(situationSegment.getSituation())) {
								situationIcon = R.drawable.icon_flood;
							}
							
							Marker marker = map.addMarker(new MarkerOptions()
		                     						.position(midPoint)
		                     						.title(situationSegment.getTrafficCondition())
		                     						//.snippet(Utilities.generateSegmentDetails(reportToRender, situationSegment))
		                     						.icon(BitmapDescriptorFactory.fromResource(situationIcon)));
						
													     //data.put("details", Utilities.generateSegmentDetails(reportToRender, situationSegment));
						     
						     // Save this marker data in your previously made HashMap mapped to the marker ID. So you can get it back based on the marker ID
						     markerDetailsMap.put(marker.getId(), Utilities.generateSegmentDetails(reportToRender, situationSegment));
							
							//hazardMap.addMarker(new MarkerOptions().position(fromPosition).title("Start"));
							//hazardMap.addMarker(new MarkerOptions().position(toPosition).title("End"));
						}
					} else {
						Toast.makeText(NotificationDetailsActivity.this, "No valid reports available", Toast.LENGTH_LONG).show();
					} 
						
				} catch (Exception ex) {
					ex.printStackTrace();
					Log.e("Hazard Map Error", "Error in rendering HazardMap: " + Utilities.getErrorMessage(ex));
					//Utilities.showDefaultAlertDialog(getActivity(), "Error", "Error in rendering hazard map details. Tap refresh button to retry.");
					refreshNotificationMap();
				}
				
				map.setInfoWindowAdapter(new InfoWindowAdapter() {

			        @Override
			        public View getInfoWindow(Marker arg0) {
			            return null;
			        }

			        @Override
			        public View getInfoContents(Marker marker) {

			            View v = getLayoutInflater().inflate(R.layout.infowindow, null);

			            TextView info= (TextView) v.findViewById(R.id.info);
			            info.setText(markerDetailsMap.get(marker.getId()));

			            return v;
			        }
			    });
			}
		}

		@Override
		protected void onCancelled() {
//			mAuthTask = null;
//			showProgress(false);
		}
		
		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			dialog = new ProgressDialog(NotificationDetailsActivity.this);
			dialog.setCancelable(false);
			dialog.setMessage("Loading..");
			dialog.isIndeterminate();
			dialog.show();
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.mcsmtms, menu);
		return true;
	}

	private View.OnClickListener backBtnOnClickListener = new View.OnClickListener() {
		@Override
		public void onClick(View v) {
			finish();
		}
	};

}
